/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package core;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import protocol.TSFile;

/**
 *
 * @author Jorge
 */
public class WorkerThread extends Thread {

    private PoolThreads threadPool;
    //private SelectionKey key;
   // private Context context;

    public WorkerThread(PoolThreads threadPool) {
        this.threadPool = threadPool;
    }

    @Override
    public void run(){
        Tupple t;
        while(true){
            LinkedList<Tupple> queue = threadPool.getQueue();
            System.out.println("Ve queue....");
            synchronized(queue){
                while(queue.isEmpty()){
                    try{
                        queue.wait();
                    }catch(InterruptedException ex){
                        ex.printStackTrace();
                    }
                }
            System.out.println("Novo elemento na queue para escrever....");
            t = queue.removeFirst();
            }
            //Executar tarefa
            ConcurrentHashMap<Integer, TSFile> mapa = threadPool.getMapa();
            TSFile file = mapa.get(t.getKey());
            if(file!=null){
                //Falta eliminar o ficheiro caso este exista para poder escrever nova informação
                synchronized(file){
                    try {
                        if(!file.isOpen()) file.openFile();
                        file.write(t.getData());
//                        if(file.isAllWrited()) {
//                            mapa.remove(t.getKey());
//                            file.getChannel().force(true);
//                            file.close();
//                            threadPool.returnOnSuccessWriting(file);
//                        }
                    } catch (IOException ex) {
                        //TODO: Falhou a escrita, fazer alguma coisa
                        Logger.getLogger(WorkerThread.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
    }

    public synchronized void serviceReadChannel(SelectionKey key) {
       // this.key = key;
       
        key.interestOps(key.interestOps());
        this.notify();
    }

    public synchronized void serviceWriteChannel(SelectionKey key) {
        //this.key = key;
        
        key.interestOps(key.interestOps());
        this.notify();
    }

    public void drainChannel(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();



        //context.setOperation((int) read(channel, 1)[0]);

        int numParams = (int) read(channel, 1)[0];
        for (int i = 0; i < numParams; i++) {
            int size = readInt(channel);
           // context.addBuffer(read(channel, size));
        }

        key.interestOps(key.OP_READ);

        key.selector().wakeup();
    }

    protected int readInt(SocketChannel channel) throws IOException {
        ByteBuffer bb = ByteBuffer.allocate(1);
        StringBuffer buffer = new StringBuffer(5);
        while (true) {
            bb.clear();
            int num = channel.read(bb);
            bb.flip();
            if (num == 1) {
                String b = Charset.defaultCharset().decode(bb).toString();
                if (b.equals(":")) {
                    return Integer.parseInt(buffer.toString());
                } else {
                    buffer.append(b);
                }
            }
            if (num < 0) {
                throw new IOException("Invalid protocol");
            }
        }
    }

    protected byte[] read(SocketChannel channel, int size) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(size);
        channel.read(buffer);
        buffer.flip();
        return buffer.array();
    }
}
